#include <stdlib.h>//NULL
#include <pthread.h>//threads
#include <unistd.h>//
#include <iostream>//cout
#include <vector>//vecteur
#include <algorithm> //foreach

#include <csignal>   
// permet d'atteindre le prototype de sigaction() et de struct sigaction





/*
 *Ce code est ....
 */

using namespace std;


/***********************************************************************************************************/

//int pthread_join(
//	 pthread_t th, 
//	 void **thread_return
//	 );
/**********************************************************************************************************/

int id=1;
int steps=100;

/****************************/
#define Object void*
#define Thread pthread_t
#define Nothing (void*) NULL
#define Fonction ((void*)(*)(void*))
/****************************/


/***************************/
Object routine(Object arg);
/**************************/




/************************************************************/
static inline void Thread_exit(Object o)
{
  pthread_exit(o);
}


void Thread_start(Thread *th)
{
  pthread_create(th,(pthread_attr_t*)NULL,routine,Nothing);
  cout << "creation du thread numero "<< id<<endl;
  id++;
}


static inline void Thread_join(Thread* th)
{
  pthread_join(*th, NULL);
}
/************************************************************/





#define PAGE_SIZE 4096


/**
 *Routine executé par le thread
 */
void* routine(void* arg)
{ 
  
  
  char * mem;
  int compteur=0;
 
  //thread qui fait: 2*steps mallocs
  //                 2*steps realloc
  //                 2*steps free
  
  while(true){
    compteur++;
    //cout << "allocation de "<< PAGE_SIZE<<" thread:" << (int) pthread_self() <<endl;
    mem = new char [PAGE_SIZE];
    
    for(int i=0;i<PAGE_SIZE;i++){
      mem[i]=('a'+i)%100;
    }
    
    delete mem;
    
    void* d = malloc(512);
    d=realloc(d,512);
    free(d);
    
    if(compteur==steps)
      break;
    
  }
  //Thread_exit(arg);
  return Nothing;
}


/*gestionnaire de signaux*/
//int sigaction (int signum, const struct sigaction * act,struct sigaction * o_act);

#include <string.h>
#include <stdio.h>

int main(int argc,char** argv)
{
    
  if(argc >=2)
  {
	steps=atoi(argv[1]);
  }
  printf("loop de taille %d\n",steps);
  //vector<Thread*> threads;
  
  pthread_t threads[10];  
 
  
  for(int i =0;i<10;i++){
    Thread_start(&threads[i]);
  }
  
  for(int i =0;i<10;i++){
    Thread_join(&threads[i]);
  }
  
  cout << "waiting threads : process "<< getpid()<<endl;
  
  //2 frees + 1 malloc + 1 calloc
  free(malloc(10));
  free(calloc(10,10));
  return 0;
}
